unit uniEnemyAircraft_Gnat;

interface

uses
  uniEnemyAircraft,
  Classes;

type
  { EnemyAircraft_Gnat }

  EnemyAircraft_Gnat = class(EnemyAircraft)
  public
    constructor Create(et: EnemyType; p: array of Single; randFact: Single = 1.0);
    destructor Destroy; override;

    procedure update; override;
    procedure init; overload; override;
    procedure init(p: array of Single; randFact: Single = 1.0); overload; override;
    procedure calcShootInterval; override;
    procedure move; override;
  end;


implementation

uses
  uniDefine,
  uniConfig,
  uniGlobal;

{ EnemyAircraft_Gnat }

procedure EnemyAircraft_Gnat.calcShootInterval;
begin
  shootInterval := Round((1.0 + FRAND * 5.0) / uniGlobal.speedAdj);
end;

constructor EnemyAircraft_Gnat.Create(et: EnemyType; p: array of Single; randFact: Single);
begin
  inherited Create(et, p, randFact);
  init(p, randFact);
end;

destructor EnemyAircraft_Gnat.Destroy;
begin
  //inherited;
end;

procedure EnemyAircraft_Gnat.init;
begin
  inherited init;
end;

procedure EnemyAircraft_Gnat.init(p: array of Single; randFact: Single);
begin
  inherited init(p, randFact);

  damage := -10;
  baseDamage := damage;
  size[0] := 0.45;
  size[1] := 0.45;
  collisionMove := 0.0;
  randMoveX := 0.5 + 0.5 * randMoveX;
  vel[0] := 0.2;
  vel[1] := 0.1;
end;

procedure EnemyAircraft_Gnat.move;
var
  _config: Config;
  hpos: PSingle;
  diff: array[0..1] of Single;
  tmp: Single;
  tmpd: Single;
  tmps: Single;
  randX: Single;
  v0, v1: Single;
  x, y, tmpX, tmpY, speed: Single;
  dist: Single;

  amt: Single;
begin
  _config := uniConfig.instance;
  if Boolean(target) then
  begin
    hpos := target.getPos;
  end
  else
  begin
    hpos := @pos;
  end;

  diff[0] := hpos^ - pos[0]; Inc(hpos);
  diff[1] := hpos^ - Pos[1];
  tmp := 0;
  tmpd := 0;
  tmps := 0;


  if target = uniGlobal._hero then
  begin
    randX := randMoveX;
  end
  else
  begin
    randX := 0.75 + FRAND * 0.15;
  end;

  tmps := 3.8;
  dist := Sqrt(diff[0] * diff[0] + diff[1] * diff[1]) * randX;
  tmpd := 0.4 + 0.6 * ((dist + 0.2 * Sin(age * 0.001)) / tmps);
  speed := tmpd * 0.25 * randX;
  tmp := (diff[0] / dist);
  x := speed * tmp;
  tmp := (diff[1] / dist);
  y := speed * tmp;
  if dist < tmp then
  begin
    tmpX := x;
    tmpY := y;
    x := tmpd * tmpX + -(1.0 - tmpd) * diff[1] / tmpd;
    y := tmpd * tmpY + (1.0 - tmpd) * diff[0] / tmpd;
    y := y + 0.01 * Sin(uniGlobal.gameFrame * 0.001);
  end
  else
  begin
    tmpd := 0.97;
    tmpX := x;
    tmpY := y;
    if randX < 0.65 then
    begin
      x := tmpd * tmpX + (1.0 - tmpd) * diff[1] / tmpd;
      y := tmpd * tmpY + -(1.0 - tmpd) * diff[0] / tmpd;
    end
    else
    begin
      x := tmpd * tmpX + -(1.0 - tmpd) * diff[1] / tmpd;
      y := tmpd * tmpY + (1.0 - tmpd) * diff[0] / tmpd;
    end;
  end;

  tmp := randX * 0.2;
  if Boolean(Round(age / 8) mod 2) then
  begin
    v0 := vel[0] * (0.85 - tmp) + (0.2 - tmp) * (randX - 0.2) * x;
  end
  else
  begin
    v0 := vel[0];
  end;
  v1 := vel[1] * (0.85 - tmp) + (0.2 + tmp) * (randX - 0.2) * y;

  if age < 50 then
  begin
    if age > 20 then
    begin
      amt := (age - 20) / 30.0;
    end
    else
    begin
      amt := 0.0;
    end;
    vel[0] := (1.0 - amt) * vel[0] + amt * v0;
    vel[0] := (1.0 - amt) * vel[0] + amt * v0;
  end
  else
  begin
    vel[0] := v0;
    vel[1] := v1;
  end;

  pos[0] := pos[0] + uniGlobal.speedAdj * vel[0];
  pos[1] := pos[1] + uniGlobal.speedAdj * vel[1];

  //-- don't allow to kill hero life...
  if pos[1] < -10.0 then pos[1] := -10.0;
  if pos[0] < -_config.screenBoundX then pos[0] := -_config.screenBoundX;
  if pos[0] > _config.screenBoundX then pos[0] := _config.screenBoundX;
end;

//-- NOTE: Many of the firing rates are not adjusted by game->speedAdj
//-- so they will not be totally correct. Should be close enough for jazz, though.
//----------------------------------------------------------

procedure EnemyAircraft_Gnat.update;
var
  v, p: array[0..2] of Single;
  hpos: PSingle;
  a, b, s: Single;
begin
  v[0] := 0.0;
  v[1] := -0.2;
  v[2] := 0.0;

  hpos := uniGlobal._hero.getPos;
  a := hpos^ - pos[0]; Inc(hpos);
  b := hpos^ - pos[1];

  //-- update age
  Inc(age);
  Dec(shootInterval);

  pos[0] := pos[0] + secondaryMove[0] * uniGlobal.speedAdj;
  pos[1] := pos[1] + secondaryMove[1] * uniGlobal.speedAdj;
  s := (1.0 - uniGlobal.speedAdj) + (uniGlobal.speedAdj * 0.7);
  secondaryMove[0] := secondaryMove[0] * s;
  secondaryMove[1] := secondaryMove[1] * s;
  move;

  p[0] := pos[0];
  p[1] := pos[1];
  p[2] := pos[2];

  if not Boolean(shootInterval) then
  begin
    calcShootInterval;
    if (Abs(a) < 2.0) and (b < 0.0) then
    begin
      v[1] := -0.39;
      p[1] := pos[1] - 0.5;
      uniGlobal._enemyAmmo.addAmmo(4, p, v);
    end;
  end;
end;

end.

